package org.darcy.framework.aspect;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.darcy.entity.SysLog;
import org.darcy.entity.SysUser;
import org.darcy.framework.annotation.BussinessLog;
import org.darcy.framework.blog.business.enums.LogLevelEnum;
import org.darcy.framework.blog.business.util.WebSpiderUtils;
import org.darcy.framework.util.AspectUtil;
import org.darcy.framework.util.RequestUtil;
import org.darcy.framework.util.SessionUtil;
import org.darcy.service.SysLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;

/**
 * AOP切面记录日志
 */
@Slf4j
@Aspect
@Component
public class BussinessLogAspect {

	@Autowired
	private SysLogService logService;

	@Pointcut(value = "@annotation(org.darcy.framework.annotation.BussinessLog)")
	public void pointcut() {
	}

	@Around("pointcut()")
	public Object writeLog(ProceedingJoinPoint point) throws Throwable {
		// 先执行业务
		Object result = point.proceed();
		try {
			handle(point);
		} catch (Exception e) {
			log.error("日志记录出错!", e);
		}
		return result;
	}

	private void handle(ProceedingJoinPoint point) throws Exception {
		Method currentMethod = AspectUtil.INSTANCE.getMethod(point);
		// 获取操作名称
		BussinessLog annotation = currentMethod.getAnnotation(BussinessLog.class);
		boolean save = annotation.save();
		String bussinessName = AspectUtil.INSTANCE.parseParams(point.getArgs(), annotation.value());
		log.info("{}, {}, {}", bussinessName, RequestUtil.getIp(), RequestUtil.getRequestUrl());
		if (!save) {
			return;
		}
		logService.asyncSaveSystemLog(getSysLog(bussinessName));
	}

	private SysLog getSysLog(String bussinessName) {
		SysLog sysLog = new SysLog();
		sysLog.setLogLevel(LogLevelEnum.INFO.toString());
		sysLog.setIp(RequestUtil.getIp());
		sysLog.setReferer(RequestUtil.getReferer());
		sysLog.setRequestUrl(RequestUtil.getRequestUrl());
		String ua = RequestUtil.getUa();
		sysLog.setUa(ua);
		sysLog.setSpiderType(WebSpiderUtils.parseUa(ua));
		sysLog.setParams(JSONObject.toJSONString(RequestUtil.getParametersMap()));
		SysUser user = SessionUtil.getUser();
		if (user != null) {
			sysLog.setUserId(user.getId());
			sysLog.setContent(String.format("用户: [%s] | 操作: %s", user.getUsername(), bussinessName));
		} else {
			sysLog.setContent(String.format("访客: [%s] | 操作: %s", sysLog.getIp(), bussinessName));
		}

		try {
			UserAgent agent = UserAgent.parseUserAgentString(ua);
			sysLog.setBrowser(agent.getBrowser().getName());
			sysLog.setOs(agent.getOperatingSystem().getName());
		} catch (Exception e) {
			log.error("日志记录，获取UserAgent出错", e);
		}
		return sysLog;
	}

}
